# -*- coding: utf-8 -*-
"""
******* 文档说明 ******
远程操作 服务器 端代码

# 当前项目: OriginCMD
# 创建时间: 2021-03-20  22:33
# 开发作者: Vincent
# 版    本: V1.0
"""
import paramiko  # pip install paramiko -i  https://pypi.tuna.tsinghua.edu.cn/simple
import os
import time
import requests


# 远程 SSH 连接，命令
class SSH(object):
    def __init__(self, hostname, port, username, password):
        self.ssh = paramiko.SSHClient()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # 连接服务器
        self.ssh.connect(
            hostname=hostname,
            port=port,
            username=username,
            password=password)

    # 命令传输
    def cmd(self, code):
        """
        :param code:  Linux  命令【部分命令不支持】
        :return:
        """
        _, stdout, stderr = self.ssh.exec_command(code)
        result = stdout.read()
        if not result:
            result = stderr.read()
        return result.decode()

    # 关闭SSH
    def close(self):
        self.ssh.close()


# 远程 SFTP 传输文件
class SFTP(object):
    def __init__(self, hostname, port, username, password):
        self.transport = paramiko.Transport(hostname, port)
        self.transport.connect(username=username, password=password)
        self.sftp = paramiko.SFTPClient.from_transport(self.transport)

    # 将本地文件放到服务器上
    def put(self, source_file, object_path):
        """
        :param source_file:   服务器待提取的文件路径及名称
        :param object_path:   待存放的本地路径
        :return:
        """
        basename = os.path.basename(source_file)
        # 将 source_file  放到服务器 object_file 路径下
        self.sftp.put(source_file, object_path + '/' + basename)
        print('{}  --> {}'.format(source_file, object_path + '/' + basename))

    # 将服务器上的文件拉到本地
    def get(self, source_file, object_path):
        """
        :param source_file:   服务器待提取的文件路径及名称
        :param object_path:   待存放的本地路径
        :return:
        """
        basename = os.path.basename(source_file)  # 文件名
        # 将服务器 source_file 文件 拉到 object_file 路径下
        self.sftp.get(source_file, os.path.join(object_path, basename))

    def close(self):
        self.transport.close()


hostname = '182.61.19.***'
port = 22
username = '****'
password = '****'

linux_ssh = SSH(
    hostname=hostname,
    port=port,
    username=username,
    password=password)

sftp = SFTP(
    hostname=hostname,
    port=port,
    username=username,
    password=password)

cmd = ''
res = 'None'
URL = 'http://{}:8899'.format(hostname)
polling_time = 0.5  # 轮询请求时间

while True:
    try:
        # 发送结果
        api_response = requests.post('{}/op'.format(URL), data=res.encode('utf-8'))
        res = 'None'
        # 下行命令
        cmd = api_response.text

        print('\r{} CMD: {}  '.format(time.strftime('%Y%m%d %H:%M:%S', time.localtime(time.time())), cmd), end='')

        # 根据命令判断 对应操作
        if cmd:
            # 后台进程命令
            if cmd.startswith('nohup'):
                os.popen(cmd)
                res = 'BackOrder: {}'.format(cmd)

            # 传送文件  上传
            elif cmd.startswith('put'):
                cmd = cmd.split('\t')
                sftp.put(cmd[1], cmd[2])

                res = 'Put Fils  {} -> {}'.format(cmd[1], cmd[2])

            # 传送文件  下载
            elif cmd.startswith('get'):
                cmd = cmd.split('\t')

                sftp.get(cmd[1], cmd[2])

                res = 'Get Fils  {} -> {}'.format(cmd[1], cmd[2])

            # 直接操作命令
            else:
                pip = os.popen(cmd)
                res = pip.buffer.read().decode(encoding='utf8')

        if res is not 'None':
            print('RES:{} '.format(res))

        time.sleep(polling_time)
    except Exception as error:
        res = 'ERROR：{}'.format(repr(error))
        print('RES:{} '.format(res))
